using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace test_device_sdk_csharp
{
    //-------------------------------------------------------------------------------------
    // 功能：事件回调函数
    // 参数：	llUserData:用户数据
    //			strEvent:数据类型  见请求数据类型定义
    // 返回：无
    //-------------------------------------------------------------------------------------
    //Function:
    //	return alert or operation information to application level.
    //Parameters :
    //	llUserData : user self - specified parameter;
    //  strEvent: detail information of callback, string type with json format.
    //Remarks :
    //	in josn string, eventType is event type, see eNetEvent declaration.
    public delegate int DataCallbackEventHandle(Int64 llUserData, string strEvent, int event_type);


    //-------------------------------------------------------------------------------------
    // 功能：帧数据回调函数
    // 参数：	stream:流句柄
    //			lpBuf:帧数据
    //			size:长度
    //			llStamp:时间戳
    //			type:类型
    //			llUserData:用户数据
    // 返回：无
    //-------------------------------------------------------------------------------------
    //Function:
    //	return decoded information to application level.
    //Parameters :
    //	stream : session handle of stream.
    //	lpBuf : video frame data;
    //	size: video frame data length;
    //	llstamp: time stamp of frame;
    //	type: frame type, see eFrameType declaration;
    //	channel: device channel (index based 1)
    //	llUserData: user self - specified parameter;
    public delegate int DataCallbackFrameHandle(IntPtr stream, IntPtr lpBuf, int size, Int64 llStamp, int type, int channel, Int64 llUserData);

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct st_work_param
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string server;
        public int port;
        public DataCallbackEventHandle callbackEvent;
        public DataCallbackFrameHandle callbackFrame;
        public Int64 llUserData;
    };

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct st_device_config
    {
        public int Length;                    // length of data buffer	// 数据缓存长度
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2048)]
        public string Buffer;             // data content				// 数据内容
    }
    

    //数据类型
    enum ENUM_DATATYPE_FrameType
    {
        em_FrameType_RHeader_Frame = 0x69643030,    //head frame			//回放头帧('00di')  i  69   j 6a  k 6b l 6c m  6d  n 6e  o 6f
        em_FrameType_Header_Frame = 0x68643030,     //head frame			//头帧('00dh')  i  69   j 6a  k 6b l 6c m  6d  n 6e  o 6f
        em_FrameType_Video_IFrame = 0x62643030,     //video main frame		//视频主帧('00db')
        em_FrameType_Video_VFrame = 0x63643030,     //video virtual frame	//视频虚帧('00dc')
        em_FrameType_Audio_Frame = 0x62773030,      //audio frame g726		//音频帧('00wb') G726
        em_FrameType_Audio_FrameT = 0x62773130,     //audio frame g711		//音频帧('01wb') G711
        em_FrameType_GPS_Frame = 0x73706730,        //gps frame				//GPS帧('0gps')
        em_FrameType_FileList_Frame = 0x74736C66,   //filelist frame		//文件列表帧('flst') 
        em_FrameType_FileListEnd_Frame = 0x6574736C,//filelist frame		//文件列表结束帧('lste') 
        em_FrameType_Snap_Frame = 0x70616e73,       //snap frame			//抓拍帧('snap') 
        em_FrameType_Data_Frame = 0x74616430,       //data frame			//数据帧('0dat') 
        em_FrameType_Status_Frame = 0x74617473,     //status frame			//状态帧('stat') 任务描述
    };

    //设备控制类型  control operation type
    enum eCtrlType
    {
        eOil_cutoff = 1,                    //cut off oil				//断开油路
        eOil_recover = 2,                   //recover oil				//恢复油路
        eCircuit_cutoff = 3,                //cut off circuit			//断开电路
        eCircuit_recover = 4,               //recover circuit			//恢复电路
        eDevice_reboot = 5,                 //reboot device				//重启设备
        eFactoryConfig_recover = 6,         //recover factory config	//恢复出厂配置
        eFormatHDD = 14,                    //format hdd				//格式化硬盘(高位表示硬盘号,硬盘号从0开始,低位表示命令号)
        eMileageClear = 15,                 //clear mileage				//里程清零
        eAlarmClear = 18,                   //clear alarm				//清除报警
    };

    //云台控制类型
    enum ePtzActionType
    {
        ePtzActionNull = 0x00,              // invalid			// 无效
        ePtzActionUp = 0x01,                // up				// 上
        ePtzActionDown = 0x02,              // down				// 下
        ePtzActionLeft = 0x03,              // left				// 左
        ePtzActionRight = 0x04,             // right			// 右
        ePtzActionLeftUp = 0x05,            // left up			// 左上
        ePtzActionRightUp = 0x06,           // right up			// 左下
        ePtzActionLeftDown = 0x07,          // left down		// 左下
        ePtzActionRigthDown = 0x08,         // right down		// 右下
        ePtzActionZoomIn = 0x09,            // zoom in(camera lens far)		// 变焦大(镜头拉远)
        ePtzActionZoomOut = 0x0a,           // zoom out(camera lens near)	// 变焦小(镜头拉近)
        ePtzActionFocusNear = 0x0b,         // focus near		// 聚焦近
        ePtzActionFocusFar = 0x0c,          // focus far		// 聚焦远
        ePtzActionIrisOpen = 0x0D,          // iris large		// 光圈扩大
        ePtzActionIrisClose = 0x0E,         // iris small		// 光圈缩小	
        ePtzActionRunCruise = 0x0F,         // run cruise		// 开始巡航
        ePtzActionStopCruise = 0x10,        // stop cruise		// 停止巡航
        ePtzActionSetPreset = 0x11,         // set preset		// 设置预置点 
        ePtzActionClearPreset = 0x12,       // clear preset		// 清除预置点 
        ePtzActionGotoPreset = 0x13,        // goto preset		// 转到预置点
        ePtzActionLightOpen = 0x14,         // open light power	// 接通灯光电源
        ePtzActionLightClose = 0x15,        // close light power// 关闭灯光电源
        ePtzActionWiperOpen = 0x16,         // open wiper switch// 接通雨刷开关
        ePtzActionWiperClose = 0x17,        // close wiper switch// 关闭雨刷开关
        ePtzActionStop = 0xFF,              // stop					//停止
    };

    public class DeviceSdk
    {
        const string cnsDllName = "SDS_Device_Sdk.dll";


        //-------------------------------------------------------------------------------------
        // 功能：初始化
        // 参数：
        // 返回：0 成功 或错误码, 见 SDS_NETDEVICE_ERR说明;
        //-------------------------------------------------------------------------------------
        //function: init
        //Return value :
        //	Error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	port: listening port;
        //	callbackEvent: callback function, see Event Callback description;
        //	llUserData: user self - specified parameter
        //
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_Init(st_work_param param); //st_work_param

        //-------------------------------------------------------------------------------------
        // 功能：停止
        // 参数：无
        // 返回：无
        //-------------------------------------------------------------------------------------
        //function:Uninitialization
        //Return value :
        //		NA
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void SDS_NetDevice_Uninit();

        //-------------------------------------------------------------------------------------
        // 功能：订阅Gps信息
        // 参数：deviceId 设备ID, 若为空, 或长度为0, 则订阅全部设备的Gps信息;  bSubscribe: true 订阅  false 取消订阅  
        // 返回：成功(= 0)或错误码, 见 SDS_NetDevice_ERR 说明;
        //-------------------------------------------------------------------------------------
        //function: Subscribe/Cancel Subscribe gps information
        //Return:
        //	Error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //  deviceId: device ID, if empty or the length of id is zero, then system assume to subscribe all owned device alert;
        //  bSubscribe: true - to subscribe; false - cancel subscribe
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_GetGPS(string deviceId, byte bSubscribe);


        //function: Subscribe/Cancel Subscribe Alert
        //Return:
        //	Error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //  deviceId: device ID, if empty or the length of id is zero, then system assume to subscribe all owned device alert;
        //  bSubscribe: true - to subscribe; false - cancel subscribe
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_GetAlarm(string deviceId, byte bSubscribe);


        //function: Request Device Information
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceId: device ID;
        // after send request, device will report its information about software version, hardware status
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_RequestDeviceInfo(string deviceId);



        //function: Open Realtime Video/Audio Stream
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceID: device ID;
        //	channel: device channel number(index based 1);
        //	stream_type:
        //		0 : main stream;
        //		1: sub stream;
        //		2: audio stream
        //	stream : session handle of stream
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_OpenStream(string deviceId, int channel, int stream_type, ref int stream);



        //-------------------------------------------------------------------------------------
        // 功能：关闭实时流  
        // 参数： stream:流句柄
        // 返回：成功(= 0)或错误码, 见 SDS_NetDevice_ERR 说明;
        //-------------------------------------------------------------------------------------
        //function:Close Realtime Video/Audio Stream
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	stream: session handle of stream；
        //	open : true : open audio stream, false : close audio stream
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_CloseStream(int stream);


        //function：Ptz Control
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	action: see ePtzActionType  description;
        //	value1: Reserved1(x speed / y speed / presetting bit);
        //	value2: Reserved2(y speed);
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_PtzCtrlOnStream(int stream, int action, int value1, int value2);


        //function：open talk
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceID: device ID;
        //	channel: device channel number(index based 1);
        //	talk: session handle of talk
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_TalkStart(string deviceId, int channel, ref int talk);

        //-------------------------------------------------------------------------------------
        // 功能：发送音频数据  
        // 参数：talk: 对讲句柄; audioType: 音频类型 lpData：音频数据 len：数据长度
        // 返回：成功(= 0)或错误码, 见 SDS_NetDevice_ERR 说明;
        //-------------------------------------------------------------------------------------
        //Send Talk Audio Data
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //talk: session handle of talk
        //	lpData：audio data
        //	len：data length
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_TalkSend(int talk, int audioType, IntPtr lpData, int len);

        //-------------------------------------------------------------------------------------
        // 功能：停止对讲 
        // 参数：talk: 对讲句柄; 
        // 返回：成功(= 0)或错误码, 见 SDS_NetDevice_ERR 说明;
        //-------------------------------------------------------------------------------------
        //function：close talk
        //Return value :
        //	NA;
        //Parameters:
        //	talk: session handle of talk
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_TalkStop(int talk);


		// Function description：Query Video or Snap Picture List
		// Parameters:
		//		[in] deviceId: device ID;
		//		[in] type:  media type, see QueryMediaType
		//		[in] startTime : start time. time format: "YYMMDD hhmmss", example: "210607 103000"
		//		[in] endTime : end time. time format "hhmmss", example "235959". only support time during one day.
		//		[in] chnFlag : Channel number list(index based 1, if equal 98, means search all channels);
		//		[out] query: API output a session handle, user may stop the query to call 
		//					the SDS_NetDevice_CloseQuery() with this session handle
		// Return value :
		//		0 is success, other is error code, see SDS_NETDEVICE_ERR description;
		// Remarks:
		//		 if success, SDK will return the json file information from event callback, as follows :
		//		 {‘num’:2, ‘filelist’ : [{‘filename’: ‘filepath1’, ‘bTime’ : ‘begin time’, ‘eTime’ : ‘end time’,
		//			‘filesize’ : 111, ‘timelen’ : 222, ‘channel’ : 1, ‘type’ : 1}, 
		//			{ ‘filename’: ‘filepath2’, ‘bTime’ : ‘begin time’, ‘eTime’ : ‘end time’, ‘filesize’ : 111,
		//			‘timelen’ : 222, ‘channel’ : 1, ‘type’ : 1 }]}
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_Query(string deviceId, int type, string startTime, string endTime, int chnFlag, ref int query);


        //function：close query
        //Return value :
        //	Error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	query: handle of this query created by SDS_NetDevice_Query;
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_CloseQuery(int query);


		//Function description：Open Remote Video Playback
		//Return value :
		//	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
		//Parameters:
		//	deviceID: device GUID;
		//	channel: device channel(index based 1)
		//	devpath: device file path,
		//	onlyIFrame: if 1, replay only with I frame, if 0, replay all frame
		//	startPos : start position of video, specified by time value, unit is second;
		//	endPos : end position of video, specified by time value, unit is second;
		//	stream: session handle of stream
		// Remarks:
		//	if endPos is set to 0, SDK will replay the whole video file.
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_ReplayStart(string deviceId, int channel, string devpath, 
			int onlyIFrame, int startPos, int endPos, ref int stream);


        //function：Close Remote Video Playback
        //Return value :
        //	Error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //stream: session handle of stream
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_ReplayStop(int stream);

        //function：device upgrade
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceId: device ID;
        //	devPath: upgrade device file path, 
        //	download: handle of upgrade session
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_UpgradeStart(string deviceId, string devPath, string version, ref int upgrade);

        //function：close upgrade
        //Return value :
        //	NA
        //Parameters :
        //	download: handle of upgrade session
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_UpgradeStop(int upgrade);


        //function：Get Device IO Status
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceId: device ID;
        //	dwInputStatus[output]: status of input ports, every bit in the DWORD represents for one port status
        //	nInputCount[output] : the number of input ports
        //	dwOutputStatus[output] : status of output ports
        //	nOutputCount[output] : the number of output ports
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_GetIoStatus(string deviceId, ref int dwInputStatus, ref int nInputCount, ref int dwOutputStatus, ref int nOutputCount);

        //function: Device Control
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceId: device ID;
        //	nCtrlType: control operation type, 1 : break oil - way 2 : restore oil - way 3 : break electric circuit 
        //              4 : restore electric circuit 5 : restart device 6 : restore Factory Settings
        //              14: format hdd   15:clear mileage   18:clear alarm
        [DllImport(cnsDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SDS_NetDevice_Ctrl(string deviceId, int nCtrlType);


        //-------------------------------------------------------------------------------------
        //function：snap picture from device
        //Return value :
        //	NA
        //Parameters :
        //	deviceId：device ID
        //	channel：device channel number (index based 1);
        //	capture: handle of capture session
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_Capture(string deviceId, int channel, ref int capture);

		//function：close download
		//Return value :
		//	NA
		//Parameters :
		//	capture: handle of capture session
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_CloseCapture(int capture);


        //-------------------------------------------------------------------------------------
        //function：download snap picture
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceId: device ID;
        //	devPath: device file path, see Query Video List description;
        //	download: handle of download session
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_DownloadSnap(string deviceId, string devPath, ref int download);


        //function：close download
        //Return value :
        //	NA
        //Parameters :
        //	download: handle of download session
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_CloseDownloadSnap(int download);


        //function: Search device on local network
        //Return value :
        //	Error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	port: scan port;
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_Search(int port);

        //-------------------------------------------------------------------------------------
        // 功能：停止搜索设备
        // 参数：
        // 返回：无
        //-------------------------------------------------------------------------------------
        //function: Stop Search device on local network
        //Return value :
        //	Error code, see SDS_NETDEVICE_ERR description;
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_StopSearch();



        // function: direct open realtime video stream
        // param：deviceId: device Ip;		channel: ( begin 1);	stream_type:  0 sub stream， 1 main stream， 2 audio stream  see eStreamType
        //		 stream: handle
        // return：0  succ     other  failed  
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_DirectOpenStream(string deviceIp, int port, int channel, int stream_type, ref int stream);


        //function: direct Close Realtime Video/Audio Stream
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	stream: session handle of stream；
        //	open : true : open audio stream, false : close audio stream
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_DirectStopStream(int stream);

        //function：direct Ptz Control
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	action: see ePtzActionType  description;
        //	value1: Reserved1(x speed / y speed / presetting bit);
        //	value2: Reserved2(y speed);
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_DirectPtzCtrl(string deviceIp, int port, int channel, int action, int value1, int value2);


        //function:Device Vendor Special Data Transport
        //Return value :
        //	SUCCESS(= 0) Or error code, see SDS_NETDEVICE_ERR description;
        //Parameters:
        //	deviceId: device ID;
        //	nType: type of transport, vendor special code.
        //	pInCfg : the data send to the device.
        //	pOutCfg[output] : the responded data from the device
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int SDS_NetDevice_TranConfigEx(string deviceId, int nType, ref st_device_config pInCfg);
    }


    public class DecodeSdk
    {
        const string cnsDllName = "temp_decode.dll";

        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int dec_Init();


        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern void dec_Uninit();


        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern void Delete();

        //open one decode channel
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int OpenDecodeChan(IntPtr hWnd, int nType);

        //close one decode channel
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int CloseDecodeChan(int nDecode);


        //input compressed video data to decode and display
        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int InputDecodeStream(int nDecode, int nDataType, IntPtr pData, int nDataLen, Int64 u64Pts);


        // play control   
        // param    nDecode    decode handle			
        //			nCtrlType  3 means control audio 	
        //			nValue     0 means close audio   1 means open audio

        [DllImport(cnsDllName, CallingConvention = CallingConvention.StdCall)]
        public static extern int CtrlPlay(int nDecode, int nCtrlType, int nValue);


  


    }
}
